#ifndef TEMPLE_UTIL_MISC_H_
#define TEMPLE_UTIL_MISC_H_

#include "util/stdc.h"
#include <atomic>
namespace util {

inline size_t align(size_t num, size_t x=sizeof(void *))
{
    return (num + x - 1) & ~(x - 1);
}

inline int get_host_addr(const string &host, string &addr)
{
    struct hostent *he;
    char buf[256];

    he = gethostbyname(host.c_str());
    if (he == NULL)
        return 1;

    if (he->h_addrtype == AF_INET)
    {
        if (inet_ntop(AF_INET, he->h_addr, buf, sizeof(buf)) == NULL)
            return 2;
    }
    else if (he->h_addrtype == AF_INET6)
    {
        if (inet_ntop(AF_INET6, he->h_addr, buf, sizeof(buf)) == NULL)
            return 3;
    }
    else
    {
        return 4;
    }

    addr = buf;
    return 0;
}

inline string get_cur_path()
{
    char buf[1024];

#ifdef WIN32
    GetCurrentDirectory(sizeof(buf), buf);
    return buf;
#else
    getcwd(buf, sizeof(buf));
    return buf;
#endif
}

inline string get_path_sep()
{
#ifdef WIN32
    return "\\";
#else
    return "/";
#endif
}

inline u64 get_cur_time()
{
#ifdef WIN32
    struct _timeb tb;
    _ftime(&tb);
    return tb.time*1000 + tb.millitm;
#else
    struct timeb tb;
    ftime(&tb);
    return tb.time*1000 + tb.millitm;
#endif
}

inline u32 get_lo32(u64 val)
{
    return (u32)(val & 0xffffffff);
}

inline u32 get_hi32(u64 val)
{
    return (u32)(val >> 32);
}

inline u64 make_u64(u32 hi, u32 lw)
{
    return (((u64)hi)<<32) + (u64)lw;
}

inline size_t file_size(const char *name)
{
    FILE *pf = fopen(name, "rb");
    if (!pf)
        return 0;

    fseek(pf, SEEK_END, 0);
    size_t len = ftell(pf);

    fclose(pf);
    return len;
}

inline std::vector<string> file_load_lines(const char *name)
{
    std::vector<string> lines;

    FILE *pf = NULL;
    char buf[8192];

    pf = fopen(name, "rb");
    if (!pf)
        return lines;

    while(fgets(buf, sizeof(buf), pf))
    {
        lines.push_back(string(buf));
    }

    fclose(pf);
    return lines;
}

inline u64 get_unique_id()
{
    static std::atomic<u64> id(1);
    return id.fetch_add(1);
}

}
#endif //TEMPLE_UTIL_MISC_H_
